using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.IO;

namespace XYTerrain.Editor
{

    public static class TerrainPreviewBaker
    {

        public static int resolution = 512;

        public static UnityEngine.SceneManagement.Scene lastScene;
        public static RenderTexture GetTerrainPreviewTex(Terrain terrainBase, string name)
        {

            RenderTexture rt = new RenderTexture(resolution, resolution, 0, UnityEngine.Experimental.Rendering.DefaultFormat.LDR);


            var previewScene = EditorSceneManager.NewPreviewScene();
            var terrain = GameObject.Instantiate(terrainBase);

            if (SceneView.lastActiveSceneView.camera != null)
            {
                 lastScene = SceneView.lastActiveSceneView.camera.scene;   
                 SceneView.lastActiveSceneView.camera.scene = previewScene;
            }

            GameObject go = terrain.gameObject;
            EditorSceneManager.MoveGameObjectToScene(go, previewScene);

            GameObject light = new GameObject("Light");
            light.transform.rotation = Quaternion.Euler(90, 0, 0);
            var l = light.AddComponent<Light>();
            l.type = LightType.Directional;
            EditorSceneManager.MoveGameObjectToScene(light, previewScene);



            GameObject cameraGo = new GameObject("PreviewCamera");
            
            EditorSceneManager.MoveGameObjectToScene(cameraGo, previewScene);


            Camera cam = cameraGo.AddComponent<Camera>();


            cam.rect = new Rect(0, 0, 1, 1);
            cam.orthographic = true;
            cam.depthTextureMode = DepthTextureMode.Depth;


            cam.rect = new Rect(0, 0, 1, 1);

            Bounds currentBounds = terrain.terrainData.bounds;

            cam.transform.eulerAngles = new Vector3(0, 0, 0);


            cam.transform.position = currentBounds.center + Vector3.up * currentBounds.max.y + new Vector3(0, 1, 0);


            Selection.activeGameObject = cam.gameObject;


            cam.transform.eulerAngles = new Vector3(90, 0, 0);

            cam.nearClipPlane = 0.5f;
            cam.farClipPlane = cam.transform.position.y + 1000.0f;


            cam.orthographicSize = Mathf.Max((currentBounds.max.x - currentBounds.min.x) / 2.0f,
                (currentBounds.max.z - currentBounds.min.z) / 2.0f);

            cam.scene = previewScene;
            cam.targetTexture = rt;
            RenderTexture.active = rt;

            cam.Render();


            cam.targetTexture =null; 

            Object.DestroyImmediate(cam);
            Object.DestroyImmediate(light);
            Object.DestroyImmediate(go);

            if (previewScene != null)
            {
                EditorSceneManager.ClosePreviewScene(previewScene);
                SceneView.lastActiveSceneView.camera.scene = lastScene;
            }

            
            return rt;
        }


        public static string[] SplitTerrainPreviewTex(RenderTexture rt,int splitTime, string savePath)
        {

            Vector2Int size = new Vector2Int(rt.width / splitTime, rt.height / splitTime);

            List<Texture2D> texList = new List<Texture2D>();

            RenderTexture.active = rt;


            var mainTex = new Texture2D(rt.width, rt.height);
            mainTex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);

            System.IO.FileStream main_file = File.Open(savePath + "/mian_Tex.png", FileMode.OpenOrCreate);
            var main_bytes = mainTex.EncodeToPNG();
            main_file.Write(main_bytes, 0, main_bytes.Length);
            main_file.Close();


            List<string> splitSavePath = new List<string>();
            string porjectSavePath = savePath.Substring(Application.dataPath.Length, savePath.Length - Application.dataPath.Length);
            for (int x = 0; x < splitTime; x++)
            {
                for (int y = 0; y < splitTime; y++)
                {
                    var temp_tex = new Texture2D(size.x, size.y);
                    temp_tex.ReadPixels(new Rect(size.x * (x ), rt.height - size.y * (y + 1), size.x, size.y), 0, 0);
                    temp_tex.name = string.Format("_x{0}_z{1}", x, y);
                    texList.Add(temp_tex);

                    string path = $"{savePath}/{temp_tex.name}.png";
                    string projectPath = $"{porjectSavePath}/{temp_tex.name}.png";
                    splitSavePath.Add(projectPath);

                    System.IO.FileStream file = File.Open(path, FileMode.OpenOrCreate);

                    var bytes = temp_tex.EncodeToPNG();
                    file.Write(bytes, 0, bytes.Length);
                    file.Close();

                }

            }
            RenderTexture.active = null;
            Object.DestroyImmediate(rt);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            texList.Clear();
            

            return splitSavePath.ToArray();



        }


    }

}

